
//1. 测试sigaction
// #include <signal.h>
// #include <iostream>
// #include <unistd.h>

// void signal_callback(int sigid)
// {
//     std::cout << "接收到:" << sigid << "号信号..." << std::endl;
// }
// int main()
// {
//     struct sigaction act;
//     act.sa_handler = signal_callback;
//     act.sa_flags = SA_RESTART;
//     sigaction(SIGINT,&act,nullptr);
//     while(true)
//     {
//         std::cout << "正在处理业务..." << std::endl;
//         sleep(1);
//     }
//     return 0;
// }


//2. 测试屏蔽信号
// #include <signal.h>
// #include <iostream>
// #include <unistd.h>

// void signal_callback(int sigid)
// {
//     std::cout << "接收到:" << sigid << "号信号..." << std::endl;
//     sleep(3);
// }
// int main()
// {
//     struct sigaction act;
//     act.sa_handler = signal_callback;
//     //act.sa_flags = SA_NODEFER;
//     // 初始化信号集
//     sigemptyset(&act.sa_mask);
//     // 添加要屏蔽的信号到信号集当中
//     sigaddset(&act.sa_mask,SIGTSTP);

//     // sigset_t mask;
//     // sigemptyset(&mask);
//     // sigaddset(&mask,SIGINT);
//     // sigprocmask(SIG_SETMASK,&mask,nullptr);
//     sigaction(SIGINT,&act,nullptr);
//     while(true)
//     {
//         std::cout << "正在处理业务..." << std::endl;
//         sleep(1);
//     }
//     return 0;
// }


//3. 统一信号源demo
// #include <sys/epoll.h>
// #include <sys/types.h> 
// #include <sys/socket.h>
// #include <unistd.h>
// #include <fcntl.h>
// #include <signal.h>
// #include <iostream>


// int pipefd[2];

// void setnoblocking(int fd)
// {
//     int old_option = fcntl(fd,F_GETFL);
//     int new_option = old_option | O_NONBLOCK;
//     fcntl(fd,F_SETFL,new_option);
// }

// // 注册事件
// void addfd(int epollfd,int fd)
// {
//     epoll_event event;
//     event.data.fd = fd;
//     event.events = EPOLLIN | EPOLLET;
//     epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);
//     setnoblocking(fd);
// }

// void signal_callback(int sig)
// {
//     int msg = sig;
//     send(pipefd[1],(char *)&sig,1,0);
// }

// void addsig(int sig)
// {
//     struct sigaction act;
//     act.sa_flags |= SA_RESTART;
//     act.sa_handler = signal_callback;
//     sigaction(sig,&act,nullptr);
// }

// int main()
// {
//     epoll_event events[1024];
//     int epollfd = epoll_create(5);// 注册5个事件表
//     socketpair(PF_UNIX,SOCK_STREAM,0,pipefd);
//     //pipe(pipefd);
//     setnoblocking(pipefd[1]);// 就算把写端设置成非阻塞的，但是写函数在信号处理函数里面，信号不到写函数就不能触发，那设置成不阻塞的有个掉毛意义
//     setnoblocking(epollfd);
//     addfd(epollfd,pipefd[0]);// 读端注册事件

//     // 如果只监听管道的读端，就会导致不向管道写入数据时一直处于不可读的状态
//     // 从而导致epoll_wait接口一直阻塞等待读端可读
//     epoll_event event;
//     event.data.fd = pipefd[1];
//     event.events = EPOLLOUT;
//     epoll_ctl(epollfd,EPOLL_CTL_ADD,pipefd[1],&event);
//     addsig(SIGINT);

//     bool stop = false;
//     while(!stop)// 主循环
//     {
//         int ret = epoll_wait(epollfd,events,sizeof(events),-1);
//         std::cout << "当前已就绪事件个数: " << ret << std::endl;
//         for(int i=0;i<ret;i++)
//         {
//             if(events[i].data.fd == pipefd[0] && events[i].events & EPOLLIN)
//             {
//                 char sigs[64];
//                 int n = read(pipefd[0],sigs,sizeof(sigs));
//                 if(n == 0) continue;
//                 else if(n > 0)
//                 {
//                     for(int i=0;i<n;i++)
//                     {
//                         switch(sigs[i])
//                         {
//                             case SIGINT: stop = true;break;
//                         }
//                     }
//                 }
//             }
//             // else if(events[i].data.fd == pipefd[1] && events[i].events & EPOLLOUT)
//             // {
//             //     std::cout << "触发管道可写事件!" << std::endl;
//             // }
//         }
//         std::cout << "正在处理业务..." << std::endl;
//         //sleep(1);
//     }
//     std::cout << "主循环终止！程序退出!" << std::endl;
//     close(pipefd[1]);
//     close(pipefd[0]);
//     return 0;
// }



//4. 测试SIGHUP信号
// #include <signal.h>
// #include <sys/types.h>
// #include <sys/stat.h>
// #include <fcntl.h>
// #include <string.h>
// #include <unistd.h>
// #include <iostream>

// void signal_callback(int sig)
// {
//     int fd = open("./lll.txt",O_CREAT | O_RDWR,0666);
//     const char *str = "测试SIGHUP信号";
//     write(fd,str,strlen(str));
//     close(fd);
// }
// int main()
// {
//     signal(SIGHUP,signal_callback);
//     while(true)
//     {
//         std::cout << "模拟正在工作中..." << std::endl;
//     }
//     return 0;
// }



//5. 测试超时事件
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <iostream>
void timeout_send()
{
    int listenfd = socket(AF_INET,SOCK_STREAM,0);
    int val = 1;

    struct timeval timeout;
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;
    setsockopt(listenfd,SOL_SOCKET,SO_SNDTIMEO,&timeout,sizeof(timeout));

    int fd = open("./lll.txt",O_RDWR | O_APPEND);
    const char *str = "测试超时机制";
    sleep(10);
    int n = send(fd,str,strlen(str),0);
    if(n == -1)
    {
        if(errno == EINPROGRESS)
        {
            std::cout << "send()函数已经被调用!" << std::endl;
        }
        else 
        {
            std::cout << "send超时机制设置错误" << std::endl;
        }
    }
    else 
    {
        std::cout << "好像没有体现出超时机制" << std::endl;
    }

    // struct sockaddr_in server;
    // memset(&server,0,sizeof(server));
    // server.sin_family = AF_INET;
    // server.sin_addr.s_addr = inet_addr("0.0.0.0");
    // server.sin_port = htons(9090);
    // bind(listenfd,(const struct sockaddr *)&server,sizeof(server));

    // listen(listenfd,5);

    // struct sockaddr_in client;
    // socklen_t len = sizeof(client);
    // int sockfd = accept(listenfd,(struct sockaddr *)&client,&len);
}
int main()
{
    timeout_send();
    return 0;
}